﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Documents;
using System.Windows;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Input;

namespace Pavilion.NodeDesigner
{
    class LineAdorner : Adorner
    {
        private Point DEFAULT_pointOnCanvas = new Point(50,50);

        private Anchor Start { get; set; }
        private Point End { get; set; }
        private AnchorVisibilityManager AnchorVisibilityManager { get; set; }       

        public LineAdorner(UIElement adornedElement, Anchor start) : base(adornedElement)
        {
            if (!(adornedElement is Canvas)) throw new ArgumentException("Line adorner may only adorn canvas.");

            Start = start;
            End = GetMousePositionOnCanvas();
            AnchorVisibilityManager = new AnchorVisibilityManager();            

            Loaded += (sender, e) => base.CaptureMouse();
           
            MouseMove += (sender, e) =>
                {
                    End = GetMousePositionOnCanvas();
                    AnchorVisibilityManager.HitTestForAnchor(adornedElement, End);
                    base.InvalidateVisual(); //Forces redraw
                };

            MouseLeftButtonDown += (sender, e) =>
                {
                    var targetAnchor = TryCreatingConnection();
                    if (targetAnchor != null)
                        (targetAnchor.FindName("anchorGrid") as Grid).Visibility = System.Windows.Visibility.Hidden;

                    AdornerLayer.GetAdornerLayer(AdornedElement).Remove(this);
                    base.ReleaseMouseCapture();
                };
        }

        private void TryMakeAnchorsVisible()
        {
            VisualTreeHelper.HitTest(AdornedElement, null,
                hitTestParameters: new PointHitTestParameters(End),
                resultCallback: result =>
                {
                    var listBoxItem = NewWayHelper.GetAncestor(result.VisualHit, typeof(ListBoxItem)) as ListBoxItem;
                    if (listBoxItem != null)
                    {
                       (listBoxItem.Template.FindName("anchorGrid", listBoxItem) as Grid)
                            .Visibility = System.Windows.Visibility.Visible;
                    }

                    return HitTestResultBehavior.Stop;
                }); 
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);

            Point start = new Point(Start.XonCanvas, Start.YonCanvas);

            var brush = new SolidColorBrush(Colors.Black); 
            var pen = new Pen(brush, 1); 
            drawingContext.DrawLine(pen, start, End);
        }

        private Point GetMousePositionOnCanvas()
        {
            var canvas = this.AdornedElement as Canvas;
        
            if (canvas == null)
                return DEFAULT_pointOnCanvas;

            return Mouse.GetPosition(canvas); 
        }

        private Anchor TryCreatingConnection()
        {
            Anchor anchor = null;   

            VisualTreeHelper.HitTest(base.AdornedElement, null,
                hitTestParameters: new PointHitTestParameters(End),
                resultCallback: (HitTestResult result) =>
                {
                    anchor = NewWayHelper.GetAncestor(result.VisualHit, typeof(Anchor)) as Anchor;
                    if (anchor != null)
                        AdornerLayer.GetAdornerLayer(base.AdornedElement).Add(new Connection(base.AdornedElement, Start, anchor));

                    return HitTestResultBehavior.Stop;
                });
            return anchor;
        }
    }
}
